package com.seer.auto.entity;

import com.seer.auto.dao.TableConfigDao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javassist.CannotCompileException;
import javassist.NotFoundException;
import lombok.Data;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Data
@ToString
@Component
public class EntityManager {

    private Map<String, MetaEntity<?>> metas = new HashMap<>();

    @Autowired
    private TableConfigDao tableConfigDao;


    private volatile Object lock = new Object();

    public Class<?> load(String name)
        throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException {
        MetaEntity<?> meta = metas.get(name);
        if (null == meta) {
            synchronized (lock) {
                if (null == meta) {
                    meta = new MetaEntity<>(loadTable(name), true);
                    metas.put(name, meta);
                }
            }
        }
        return meta.getClazz();
    }

    public MetaEntity<?> getMeta(String name)
        throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException {
        MetaEntity<?> meta = metas.get(name);
        if (null == meta) {
            load(name);
        }
        return metas.get(name);
    }

    public List<Table> loadTable() {
        return new ArrayList<>(tableConfigDao.listTables().values());
    }


    public Table loadTable(String name) {
        return tableConfigDao.findByTableName(name);
    }

    public <T> T create(String model, Map<String, Object> params)
        throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException {
        return (T) getMeta(model).getFactory().create(params);
    }
}
